﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.CodeDom.Compiler;
using System.IO;
using System.Windows.Forms;
using Microsoft.CSharp;


namespace AtfutureCodeMachine
{
    public class Fun
    {
        public static object ParseNew()
        {
            string strCSPath = Path.Combine(Application.StartupPath,
                "fun");

            StringBuilder sb = new StringBuilder();
            foreach (FileInfo fi in (new DirectoryInfo(strCSPath)).GetFiles("*.cs"))
            {
                using (StreamReader sr = new StreamReader(fi.FullName, Encoding.GetEncoding("gb2312")))
                {
                    sb.Append(sr.ReadToEnd());
                    sb.AppendLine();
                }
            }

            return AtfutureEvaluatorNew.ExecuteCode(sb.ToString());
        }
    }

    class AtfutureEvaluatorNew
    {
        #region 执行静态代码
        /// <summary>
        /// 执行代码，返回结果(默认引用了System.dll、System.Data.dll、System.Xml.dll、System.Web.dll 4个程序集)
        /// </summary>
        /// <param name="code">代码</param>
        /// <param name="arrReferencedAssemblies">要引用的程序集</param>
        /// <returns></returns>
        public static object ExecuteCode(string funCode)
        {
            CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();

            CompilerParameters objCompilerParameters = new CompilerParameters();
            objCompilerParameters.ReferencedAssemblies.Add("System.dll");       //引用dll 
            objCompilerParameters.ReferencedAssemblies.Add("System.Data.dll");  //引用dll 
            objCompilerParameters.ReferencedAssemblies.Add("System.Xml.dll");   //引用dll 
            objCompilerParameters.ReferencedAssemblies.Add("System.Web.dll");   //引用dll 
            objCompilerParameters.ReferencedAssemblies.Add("AtfutureCustom.dll");   //引用dll


            objCompilerParameters.GenerateExecutable = false;
            objCompilerParameters.GenerateInMemory = true;

            CompilerResults cr = (objCSharpCodePrivoder.CompileAssemblyFromSource(objCompilerParameters,
            new[] { GenerateCode(funCode) }));

            if (cr.Errors.HasErrors)
            {
                StringBuilder l_err = new StringBuilder("编译错误：");
                foreach (CompilerError err in cr.Errors)
                {
                    l_err.AppendLine(err.ErrorText);
                }
                return l_err.ToString();
            }

            try
            {
                // 通过反射，调用HelloWorld的实例 
                Assembly objAssembly = cr.CompiledAssembly;
                return objAssembly.CreateInstance("Atfuture.AtfutureClass");
            }
            catch (Exception err)
            {
                throw new Exception("动态解析 cs代码 出错:" + err.Message);
            }
        }

        private static string GenerateCode(string fun)
        {
            StringBuilder sb = new StringBuilder();
            sb.Append("using System;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.Text;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.IO;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.Data;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.Xml;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.Web;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.Collections;");
            sb.Append(Environment.NewLine);
            sb.Append("using System.Collections.Generic;");
            sb.Append("using AtfutureCustom;");
            sb.Append(Environment.NewLine);
            sb.Append("namespace Atfuture");
            sb.Append(Environment.NewLine);
            sb.Append("{");
            sb.Append(Environment.NewLine);
            sb.Append(" public class AtfutureClass");
            sb.Append(Environment.NewLine);
            sb.Append(" {");
            sb.Append(Environment.NewLine);
            sb.Append(fun);
            sb.Append(Environment.NewLine);
            sb.Append(" }");
            sb.Append(Environment.NewLine);
            sb.Append("}");

            return sb.ToString();
        }
        #endregion
    }
}